package com.itfreer.gis.data.database;

import com.itfreer.file.LocalObjectBase;
import com.itfreer.gis.data.file.ShapeFileDataEditServer;
import com.itfreer.utils.zip.ZipperUtils;
import com.itfreer.utils.zip.ZipperUtils.FileEntry;

import org.geotools.geojson.feature.FeatureJSON;
import org.geotools.geojson.geom.GeometryJSON;
import org.locationtech.jts.geom.Geometry;
import org.opengis.feature.Property;
import org.opengis.feature.simple.SimpleFeature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 定义数据导出实现类
 */
@Component
public class DataExportServiceImp extends LocalObjectBase implements DataExportService {

	@Autowired
	private GeoToolsDataEditServer postGISDataEditServer;
	@Autowired
	private ShapeFileDataEditServer shapeFileAnalysis;

	/**
	 * 文件导出为shape文件
	 * 
	 * @param source
	 *            源数据表名
	 * @param target
	 *            目录数据文件名称，只需要名称，如:ZY_LDGX
	 * @param where
	 *            条件
	 * @return 导入的zip文件路径
	 * @throws Exception
	 */
	@Override
	public String exportShape(String source, String target, String where) throws Exception {
		// 将导出数据，放到系统运行的临时目录
		String basePath = getBasePath();
		if (!basePath.endsWith("/")) {
			basePath += "/";
		}
		File basePathFile = new File(basePath);
		if (!basePathFile.isDirectory()) {
			basePathFile.mkdirs();
		}

		// 临时路径
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		String ymd = sdf.format(new Date());
		String filePath = "export/" + ymd + "/" + UUID.randomUUID().toString().replaceAll("-", "") + "/";
		File filePathFile = new File(basePath + filePath);
		if (!filePathFile.isDirectory()) {
			filePathFile.mkdirs();
		}

		// 查询数据表中的要素
		List<SimpleFeature> datas = postGISDataEditServer.queryFeature(source, where);
		if (datas == null) {
			datas = new ArrayList<>();
		}
		// 将数据导出到临时文件中
		String outFilePath = basePath + filePath + target + ".shp";
		shapeFileAnalysis.addFeatures(outFilePath, datas, postGISDataEditServer.getTableMetadata(source));

		// 压缩文件
		String zipFilePath = basePath + filePath + target + ".zip";
		FileOutputStream zipFile = new FileOutputStream(zipFilePath);
		List<FileEntry> fileEntrys = new ArrayList<>();

		String dbfFilePath = basePath + filePath + target + ".dbf";
		addZip(fileEntrys, dbfFilePath);

		String prjFilePath = basePath + filePath + target + ".prj";
		addZip(fileEntrys, prjFilePath);

		String shpFilePath = basePath + filePath + target + ".shp";
		addZip(fileEntrys, shpFilePath);

		String shxFilePath = basePath + filePath + target + ".shx";
		addZip(fileEntrys, shxFilePath);

		String fixFilePath = basePath + filePath + target + ".fix";
		addZip(fileEntrys, fixFilePath);

		ZipperUtils.zip(zipFile, fileEntrys);
		return zipFilePath.replace(basePath, "");
	}

	/**
	 * 文件导出为geojson
	 * 
	 * @param source
	 *            源数据表名
	 * @param target
	 *            目标数据文件名称，只需要名称，如:ZY_LDGX
	 * @param where
	 *            条件
	 * @return 导入的zip文件路径
	 * @throws Exception
	 */
	@Override
	public String exportGeoJson(String source, String target, String where) throws Exception {
		// 将导出数据，放到系统运行的临时目录
		String basePath = getBasePath();
		if (!basePath.endsWith("/")) {
			basePath += "/";
		}
		File basePathFile = new File(basePath);
		if (!basePathFile.isDirectory()) {
			basePathFile.mkdirs();
		}

		// 临时路径
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		String ymd = sdf.format(new Date());
		String filePath = "export/" + ymd + "/" + UUID.randomUUID().toString().replaceAll("-", "") + "/";
		File filePathFile = new File(basePath + filePath);
		if (!filePathFile.isDirectory()) {
			filePathFile.mkdirs();
		}

		// 查询数据表中的要素
		List<SimpleFeature> datas = postGISDataEditServer.queryFeature(source, where);
		if (datas == null) {
			datas = new ArrayList<>();
		}

		// 将数据导出到临时文件中
		String outFilePath = basePath + filePath + target + ".geojson";
		OutputStream outputStream = new FileOutputStream(outFilePath);
		FeatureJSON fjson = new FeatureJSON();
		for (SimpleFeature sFeature : datas) {
			fjson.writeFeature(sFeature, outputStream);
		}
		outputStream.flush();
		outputStream.close();

		// 压缩文件
		String zipFilePath = basePath + filePath + target + ".zip";
		FileOutputStream zipFile = new FileOutputStream(zipFilePath);
		List<FileEntry> fileEntrys = new ArrayList<>();

		String dbfFilePath = basePath + filePath + target + ".geojson";
		addZip(fileEntrys, dbfFilePath);

		ZipperUtils.zip(zipFile, fileEntrys);
		return zipFilePath.replace(basePath, "");
	}

	/**
	 * 文件导出为geojson
	 * 
	 * @param source
	 *            源数据表名
	 * @param target
	 *            目标数据文件名称，只需要名称，如:ZY_LDGX
	 * @param where
	 *            条件
	 * @return 导入的zip文件路径
	 * @throws Exception
	 */
	@Override
	public List<Map<String, Object>> exportMap(String source, String where) throws Exception {
		// 查询数据表中的要素
		List<SimpleFeature> datas = postGISDataEditServer.queryFeature(source, where);
		if (datas == null) {
			return null;
		}

		List<Map<String, Object>> results = new ArrayList<>();
		GeometryJSON g = new GeometryJSON(15);
		try {
			for (SimpleFeature item : datas) {
				Map<String, Object> data = new HashMap<>();
				for (Property p : item.getProperties()) {
					String key = p.getName().toString();
					if (key.equals("geom")) {
						continue;
					}
					data.put(key, p.getValue());
				}
				StringWriter sw = new StringWriter();
				g.write((Geometry) item.getDefaultGeometry(), sw);
				data.put("sgeom", sw.toString());
				results.add(data);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return results;
	}

	private void addZip(List<FileEntry> fileEntrys, String fixFilePath) {
		File fixFile = new File(fixFilePath);
		if (fixFile.exists()) {
			FileEntry fixFileEntry = new FileEntry(null, fixFile);
			fileEntrys.add(fixFileEntry);
		}
	}
}
